package com.harmony.pilot.completion.service.impl;

import com.harmony.pilot.completion.service.CacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.function.Supplier;

/**
 * 缓存服务实现
 * 提供查询结果缓存和性能优化
 */
@Service
@Slf4j
public class CacheServiceImpl implements CacheService {
    
    private final ConcurrentHashMap<String, CacheEntry> cache = new ConcurrentHashMap<>();
    
    @Override
    public <T> Optional<T> get(String key, Class<T> type) {
        CacheEntry entry = cache.get(key);
        if (entry == null) {
            return Optional.empty();
        }
        
        // 检查是否过期
        if (entry.isExpired()) {
            cache.remove(key);
            return Optional.empty();
        }
        
        @SuppressWarnings("unchecked")
        T value = (T) entry.getValue();
        return Optional.of(value);
    }
    
    @Override
    public <T> void put(String key, T value, int ttlSeconds) {
        long expireTime = System.currentTimeMillis() + (ttlSeconds * 1000L);
        cache.put(key, new CacheEntry(value, expireTime));
    }
    
    @Override
    public void evict(String key) {
        cache.remove(key);
    }
    
    @Override
    public void clear() {
        cache.clear();
    }
    
    @Override
    @SuppressWarnings("unchecked")
    public <T> T getOrCompute(String key, Supplier<T> supplier, int ttlSeconds) {
        Optional<T> cached = get(key, (Class<T>) Object.class);
        if (cached.isPresent()) {
            return cached.get();
        }
        
        T value = supplier.get();
        put(key, value, ttlSeconds);
        return value;
    }
    
    @Override
    public <T> CompletableFuture<T> getOrComputeAsync(String key, Supplier<T> supplier, int ttlSeconds) {
        return CompletableFuture.supplyAsync(() -> getOrCompute(key, supplier, ttlSeconds),
                Executors.newCachedThreadPool());
    }
    
    /**
     * 缓存条目
     */
    private static class CacheEntry {
        private final Object value;
        private final long expireTime;
        
        public CacheEntry(Object value, long expireTime) {
            this.value = value;
            this.expireTime = expireTime;
        }
        
        public Object getValue() {
            return value;
        }
        
        public boolean isExpired() {
            return System.currentTimeMillis() > expireTime;
        }
    }
}

